package com.googlecode.wicketslides;

import java.util.ArrayList;
import java.util.List;

import org.apache.wicket.Component;
import org.apache.wicket.behavior.AbstractBehavior;
import org.apache.wicket.markup.html.IHeaderResponse;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.request.resource.PackageResourceReference;

/**
 * This class provide a almost-out-of-the-box wicket Panel with a smoothgallery
 * in it. What is missing are Mootools resources cause they should be added
 * outside the panel.
 * 
 * To add the Mootools javascript resources just make:
 * 
 * <code>
 * response.renderJavaScriptReference(new PackageResourceReference(WicketSlides.class,
 * 			WicketSlides.MOOTOOLS));
 * response.renderJavaScriptReference(new PackageResourceReference(WicketSlides.class,
 * 			WicketSlides.MOOTOOLS_MORE));
 * </code>
 * 
 * in #renderHead(final IHeaderResponse response) of a WebPage or a Component in
 * a parent container of the SlidesPanel instance.
 * 
 * @author ildella
 * 
 */
public class SlidesPanel extends Panel
{

	private static final long serialVersionUID = 1L;

	List<SlideshowImage> imageList;
	List<SlideshowImage> thumbList;
	Boolean thumbs;
	Integer width;
	Integer height;
	String useHistoryManager;
	Integer thumbWidth;
	Integer thumbHeight;
	Boolean timed;
	Integer fadeDuration;
	Integer delay;
	Boolean showArrow;
	Boolean embedLinks;
	Boolean showInfoPane;
	String carouselText;

	SlidesPanel(final String id)
	{
		super(id);
	}

	@SuppressWarnings("deprecation")
	void processPanel()
	{
		this.add(new AbstractBehavior()
		{
			private static final long serialVersionUID = 1L;

			@Override
			public void renderHead(final Component component, final IHeaderResponse response)
			{
				response.renderString("<style type=\"text/css\">" + "#myGallery" + "{	width: "
						+ SlidesPanel.this.width + "px; height:" + SlidesPanel.this.height
						+ "px; z-index:5; border: 0; } " + "</style>");
				response.renderCSSReference(new PackageResourceReference(WicketSlides.class,
						WicketSlides.JD_GALLERY_CSS));
				response.renderJavaScriptReference(new PackageResourceReference(WicketSlides.class,
						WicketSlides.JD_GALLERY));
			}
		});
		this.add(new AbstractBehavior()
		{
			private static final long serialVersionUID = 1L;

			@Override
			public void renderHead(final Component component, final IHeaderResponse response)
			{
				final StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.append("");
				stringBuilder.append("var myGallery = new gallery($('myGallery'), {");
				stringBuilder.append("timed: ");
				stringBuilder.append(SlidesPanel.this.timed);
				stringBuilder.append(", ");
				stringBuilder.append("fadeDuration: ");
				stringBuilder.append(SlidesPanel.this.fadeDuration);
				stringBuilder.append(", ");
				stringBuilder.append("delay: ");
				stringBuilder.append(SlidesPanel.this.delay);
				stringBuilder.append(", ");
				stringBuilder.append("useHistoryManager: ");
				stringBuilder.append(SlidesPanel.this.useHistoryManager);
				stringBuilder.append(", ");
				stringBuilder.append("thumbWidth: ");
				stringBuilder.append(SlidesPanel.this.thumbWidth);
				stringBuilder.append(", ");
				stringBuilder.append("thumbHeight: ");
				stringBuilder.append(SlidesPanel.this.thumbHeight);
				stringBuilder.append(", ");
				stringBuilder.append("showInfopane: ");
				stringBuilder.append(SlidesPanel.this.showInfoPane);
				stringBuilder.append(", ");
				stringBuilder.append("embedLinks: ");
				stringBuilder.append(SlidesPanel.this.embedLinks);
				stringBuilder.append(", ");
				stringBuilder.append("thumbCloseCarousel: true, ");
				stringBuilder.append("showCarouselLabel: true, ");
				stringBuilder.append("textShowCarousel: '" + SlidesPanel.this.carouselText + "', ");
				stringBuilder.append("showArrows: ");
				stringBuilder.append(SlidesPanel.this.showArrow);
				stringBuilder.append(", ");
				stringBuilder.append("showCarousel: ");
				stringBuilder.append(SlidesPanel.this.thumbs);
				stringBuilder.append(" ");
				stringBuilder.append("});");
				stringBuilder.append((SlidesPanel.this.thumbs ? "myGallery.showCarousel();" : ""));
				stringBuilder.append(Boolean.TRUE.equals(Boolean
						.parseBoolean(SlidesPanel.this.useHistoryManager))
						? "HistoryManager.start();"
						: "");
				final String javascript = stringBuilder.toString();
				response.renderOnDomReadyJavaScript(javascript);
			}

		});

		final ListView<SlideshowImage> listview = new ListView<SlideshowImage>("imageElement",
				this.imageList)
		{

			@Override
			protected void populateItem(final ListItem<SlideshowImage> item)
			{
				SlidesPanel.this.loader.populate(item);
			}

		};

		this.add(listview);

	}

	ImageLoader loader;

	public static class Builder
	{
		private final String id;
		private List<SlideshowImage> imageList = new ArrayList<SlideshowImage>(1);
		private List<SlideshowImage> thumbList = new ArrayList<SlideshowImage>(1);
		private Boolean thumbs = false;
		private Integer width = 480;
		private Integer height = 360;
		private Integer thumbWidth = 48;
		private Integer thumbHeight = 36;
		private Boolean timed = false;
		private Integer fadeDuration = 600;
		private Integer delay = 6000;
		private Boolean showArrow = true;
		private final Boolean embedLinks = true;
		private final Boolean showInfoPane = true;
		private ImageLoader loader = new ImageLoader();
		private Boolean useHistoryManager = Boolean.FALSE;
		private String carouselText;

		public Builder(final String id)
		{
			this.id = id;
		}

		public SlidesPanel build()
		{
			final SlidesPanel panel = new SlidesPanel(this.id);
			panel.imageList = this.imageList;
			panel.thumbList = this.thumbList;
			panel.thumbs = this.thumbs;
			panel.width = this.width;
			panel.height = this.height;
			panel.thumbWidth = this.thumbWidth;
			panel.thumbHeight = this.thumbHeight;
			panel.useHistoryManager = this.useHistoryManager.toString();
			panel.timed = this.timed;
			panel.fadeDuration = this.fadeDuration;
			panel.delay = this.delay;
			panel.showArrow = this.showArrow;
			panel.embedLinks = this.embedLinks;
			panel.showInfoPane = this.showInfoPane;
			panel.carouselText = this.carouselText;
			panel.loader = this.loader;
			if (this.thumbs == null)
			{
				if (this.thumbList.contains(null)
						|| (this.imageList.size() != this.thumbList.size()))
				{
					panel.thumbs = false;
				}
				else if (this.imageList.size() == this.thumbList.size())
				{
					panel.thumbs = true;
				}
			}

			panel.processPanel();
			return panel;
		}

		public Builder showThumbs(final Boolean showThumbs)
		{
			if (showThumbs == null)
			{
				this.thumbs = false;
			}
			this.thumbs = showThumbs;
			return this;
		}

		public Builder thumbList(final List<SlideshowImage> thumbList)
		{
			if ((thumbList == null) || thumbList.isEmpty())
			{
				this.thumbs = false;
			}
			this.thumbList = thumbList;
			return this;
		}

		public Builder size(final Integer width, final Integer height)
		{
			if ((width == null) || (height == null))
			{
				throw new IllegalArgumentException(
						"Either provide both width and height, or don't call size() at all");
			}
			this.width = width;
			this.height = height;
			return this;
		}

		public Builder thumbSize(final Integer width, final Integer height)
		{
			if ((width == null) || (height == null))
			{
				throw new IllegalArgumentException(
						"Either provide both width and height, or don't call size() at all");
			}
			this.thumbWidth = width;
			this.thumbHeight = height;
			return this;
		}

		public Builder timed(final Boolean timed)
		{
			this.timed = timed;
			return this;
		}

		public Builder showArrow(final Boolean showArrow)
		{
			this.showArrow = showArrow;
			return this;
		}

		public Builder fadeDuration(final Integer fadeDuration)
		{
			this.fadeDuration = fadeDuration;
			return this;
		}

		public Builder delay(final Integer delay)
		{
			this.delay = delay;
			return this;
		}

		public Builder historyManager(final boolean useHistoryManager)
		{
			this.useHistoryManager = useHistoryManager;
			return this;
		}

		public Builder carouselText(final String carouselText)
		{
			this.carouselText = carouselText;
			return this;
		}

		public Builder addImage(final String imageUrl, final String thumbUrl)
		{
			this.imageList.add(new SlideshowImageImpl("", "", "", imageUrl));
			this.thumbList.add(new SlideshowThumbnail("", thumbUrl));
			return this;
		}

		public Builder addImage(final String imageUrl)
		{
			this.imageList.add(new SlideshowImageImpl("", "", "", imageUrl));
			return this;
		}

		public Builder addImageList(final List<SlideshowImage> listImagesUrl)
		{
			this.imageList = listImagesUrl;
			return this;
		}

		public Builder addThumbList(final List<SlideshowImage> listThumbsUrl)
		{
			this.thumbList = listThumbsUrl;
			return this;
		}

		public Builder loadImageWith(final ImageLoader loader)
		{
			this.loader = loader;
			return this;
		}

		public void addImage(final SlideshowImage mainImage, final SlideshowImage thumbImag2)
		{
			this.imageList.add(mainImage);
			this.thumbList.add(thumbImag2);
		}

	}

}
